package com.zhu.rpc.server.handler;

import com.zhu.rpc.JsonUtil;
import com.zhu.rpc.MsgType;
import com.zhu.rpc.RpcMethod;
import com.zhu.rpc.SpringContextUtil;
import com.zhu.rpc.msgBean.RpcResponseBean;
import com.zhu.rpc.msgBean.ServerInitBean;
import com.zhu.rpc.server.ResponseMessageCache;
import com.zhu.rpc.server.RpcProtocolProviderBean;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.lang.reflect.Method;

public class RpcHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //暂时默认连接建立时发送
        ServerInitBean serverInitBean = new ServerInitBean();
        serverInitBean.setExposeMethod(RpcMethod.providerMethodMap.keySet());
        ctx.channel().writeAndFlush(MsgType.init.id+JsonUtil.toJson(serverInitBean));
        super.channelActive(ctx);
    }

    //TODO 注意这个堆外内存释放

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        RpcProtocolProviderBean protocolBean = (RpcProtocolProviderBean) msg;
        Method method = RpcMethod.providerMethodMap.get(protocolBean.getName());
        Object rtn;
        try {
            rtn =  protocolBean.getoParam()==null?method.invoke
                    (SpringContextUtil.getBean(RpcMethod.providerClassAlias.get(protocolBean.getName().split(",")[0])))
                    :method.invoke(SpringContextUtil.getBean(RpcMethod.providerClassAlias.get(protocolBean.getName().split(",")[0]))
                    ,protocolBean.getoParam());
        }catch (Exception e){
            RpcResponseBean responseBean = new RpcResponseBean(protocolBean.getMsgId(),"",true,e.getMessage());
            String responseMsg = MsgType.callResp.id+JsonUtil.toJson(responseBean);
            //调用异常
            ResponseMessageCache.cacheResponseMsg(responseBean.getMsgId(),responseMsg);
            ctx.channel().writeAndFlush(responseMsg);
            return;
        }

        if (method.getReturnType() != void.class){
            //有返回才返回
            RpcResponseBean responseBean = new RpcResponseBean(protocolBean.getMsgId(),rtn,false,"suc");
            String responseMsg = MsgType.callResp.id+JsonUtil.toJson(responseBean);
            ResponseMessageCache.cacheResponseMsg(responseBean.getMsgId(),responseMsg);
            ctx.channel().writeAndFlush(responseMsg);
        }
        super.channelRead(ctx, msg);
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        System.out.println("异常到了这里");

    }
}
